<!DOCTYPE html>
<head>
	<title></title>
	<script type="text/javascript">
	

		//  //53
		function Class () {
			var aDefine=arguments[arguments.length-1];
			if (!aDefine)
				return;

			var aBase=arguments.length>1?arguments[0]:object;

			function prototype_ () { };
			prototype_.prototype=aBase.prototype;
			var aPrototype=new prototype_();

			for(var member in aDefine)
			{
				if(member!="Create")
					aPrototype[member]=aDefine[member];
			}

			if(aDefine.Create)
				var aType=aDefine.Create;
			else
			{
				aType=function () {
					this.base.apply(this,arguments);
				}
			}

			aType.prototype=aPrototype;
			aType.Base=aBase;
			aType.prototype.Type=aType;
			return aType;
		}
		function object(){};
		object.prototype.isA=function (aType) {
			var self=this.Type;
			while(self)
			{
				if(self==aType)
					return true;
				self=self.Base;
			}
			return false;
		}

		object.prototype.base=function () {
			var Caller=object.prototype.base.caller;
			Caller && Caller.Base && Caller.Base.apply(this,arguments);
		}

		var Person=Class
		(
			{
				Create:function (name,age) {
					this.base();
					this.name=name;
					this.age=age;
				},
				SayHello:function () {
					alert("Hello,I am "+this.name+","+this.age+" years old.")
				}
			}
		);
		var Employee=Class(Person,
			{
				Create:function (name,age,salary) {
					this.base(name,age);
					this.salary=salary;
				},
				ShowMeTheMoney:function () {
					alert(this.name+" $"+this.salary);
				}

			}
		);
		var BillGates=new Person("Bill gates",53);
		var SteveJobs=new Employee("Steve jobs",53,1234);
		BillGates.SayHello();
		SteveJobs.SayHello();
		SteveJobs.ShowMeTheMoney();

		var LittleBill=new BillGates.Type("Little bill",6);
		LittleBill.SayHello();

		alert(BillGates.isA(Person));
		alert(BillGates.isA(Employee));
		alert(SteveJobs.isA(Person));



	/*

		// 利用prototype创建对象,及继承类 //50
		var object=
		{
			isA:function (aType) 
			{
				var self=this;
				while(self)
				{
					if(self==aType)
						return true;
					self=self.Type;
				}
				return false;
			}
		}
		//创建类的函数,用于声明类及继承的关系
		function Class (aBaseClass,aClassDefine) {
			//创建类的临时函数壳
			function class_ () {
				//给每个类约定一个Type属性,引用其继承的类
				this.Type=aBaseClass;
				for (var member in aClassDefine) {
					//复制类的全部定义到当前创建的类
					this[member]=aClassDefine[member];
				};
			}
			class_.prototype=aBaseClass;
			return new class_();
		}
		//创建对象的函数,用户任意类的对象创建
		function New (aClass,aParams) {
			//创建对象的临时函数壳
			function new_ () {
				//给每个对象约定一个Type属性,据此可以访问到对象所属的类
				this.Type=aClass;
				//约定所有类的构造函数都叫Create
				if(aClass.Create)
					aClass.Create.apply(this,aParams);
			}
			new_.prototype=aClass;
			return new new_();
		}
		//派生自object基本类
		var Person=Class(object,
		{
			Create:function (name,age) 
			{
				this.name=name;
				this.age=age;
			},
			SayHello:function () {
				alert("Hello,I am "+this.name+","+this.age+" years old.");
			}
		})
		//派生自Person类
		var Employee=Class(Person,
		{
			Create:function (name,age,salary) {
				//调用基类的构造函数,call传递this指针
				Person.Create.call(this,name,age);
				this.salary=salary;
			},
			ShowMeTheMoney:function () {
				alert(this.name+" $"+this.salary);
			}
		})
		var BillGates=New(Person,["Bill gates",53]);
		var SteveJobs=New(Employee,["Steve jobs",53,1234]);
		BillGates.SayHello();
		SteveJobs.SayHello();
		SteveJobs.ShowMeTheMoney();

		var LittleBill=New(BillGates.Type,["Little bill",6]);
		LittleBill.SayHello();

		alert(BillGates.isA(Person));
		alert(BillGates.isA(Employee));
		alert(SteveJobs.isA(Person));
		alert(Person.isA(Employee));
		alert(Employee.isA(Person));
		// for(var a in LittleBill.Type)
		// 	alert(a);




		// prototype 甘露模型1 //
		var Person={
			Create:function (name,age) {
				this.name=name;
				this.age=age;
			},
			SayHello:function () {
				alert("Hello, I am "+this.name);
			},
			HowOld:function () {
				alert(this.name+" is "+this.age+" years old.");
			}
		}
		function New (aClass,aParams) {
			function new_ () {
				aClass.Create.apply(this,aParams);//apply函数
			}
			new_.prototype=aClass;
			return new new_();
		}
		var BillGates=New(Person,["Bill gates",53]);
		BillGates.SayHello();
		BillGates.HowOld();
		alert(BillGates.constructor==Object);




		// prototype的继承 //
		//定义构造函数
		function Person (name) {
			this.name=name;
		}
		//方法定义到构造函数的prototype上
		Person.prototype.SayHello=function () {
			alert('Hello,I am '+this.name);
		}
		//之类构造函数
		function Employee (name,salary) {
			Person.call(this.name);//调用上层构造函数
			this.salary=salary;//之类自己的成员
		}
		//子类构造函数要先调上层构造函数来建立prototype对象实现继承
		//只需要prototype的方法,其他东西无意义
		Employee.prototype=new Person();
		//将之类的方法定义到构造函数上
		Employee.prototype.ShowMeTheMoney=function()
		{
			alert(this.name+' $'+this.salary);
		}
		var BillGates=new Person("Bill gates");
		BillGates.SayHello();

		var SteveJobs=new Employee("Steve jobs",1234);
		SteveJobs.SayHello();
		SteveJobs.ShowMeTheMoney();

		alert(BillGates.SayHello==SteveJobs.SayHello);



	

		// 闭包(类) //
		function Person (firstName,lastName,age) {
			//私有变量
			var _firstName=firstName;
			var _lastName=lastName;

			//公有变量
			this.age=age;

			//方法
			this.getName=function () {
				return(_firstName+" "+_lastName);
			}
			this.SayHello=function () {
				alert("Hello, I am "+_firstName+" "+_lastName);
			}
		}
		var BillGates=new Person("Bill","gates",53);
		var SteveJobs=new Person("Steve","jobs",54);

		BillGates.SayHello();
		SteveJobs.SayHello();
		alert(BillGates.getName()+" "+BillGates.age);
		alert(BillGates._firstName);//无法访问私有变量




		// 利用prototype扩展内置对象的扩展方法 //
		String.prototype.myPro=function String$myPro() {
			return 'mypro['+this.replace(/^\s+|\s+$/g,'')+']';
		}
		function putMsg (name) {
			tmp= name.myPro();
			alert(tmp);
		}
		putMsg('  asdfsad  ');




		// 动态给对象添加新的属性和方法 //
		function Person (name) {
			this.name=name;
		}
		Person.prototype.SayHello=function () {
			alert("Hello,I am "+this.name+this.kk);
		}
		var BillGates=new Person("Bill gates");
		Person.prototype.kk='hu hu hu hu'
		BillGates.SayHello();

		Person.prototype.Retire=function () {
			alert("ha ha "+this.newPrototype+",bye bye");
		}
		Person.prototype.newPrototype='I am the new prototype';
		BillGates.Retire();

		var test=new Person('nini');
		test.Retire();//此时Person直接就有了Retire方法,直接用





		// 重载(override)prototype的属性和函数,不影响原型 //
		function Person (name) {
			this.name=name;
		}
		Person.prototype.company="Microsoft";

		Person.prototype.SayHello=function () {
			alert("Hello, I am "+this.name+" of "+this.company);
		}

		var BillGates=new Person("Bill gates");
		BillGates.SayHello();

		var SteveJobs=new Person("steve jobs");
		SteveJobs.company="Apple";
		SteveJobs.SayHello=function () {
			alert("Hi, "+this.name+" like "+this.company+", ha ha");
		}
		SteveJobs.SayHello();//用自己重写后的输出
		BillGates.SayHello();//不会因为被重写而导致原来的也改了
	


		// prototype //
		function Person (name) {
			this.name=name;
		}
		Person.prototype.SayHello=function()
		{
			alert('Hello ,i am '+this.name);
		}
		var BillGates=new Person('Bill gates');
		var SteveJobs=new Person('Steve jobs');

		BillGates.SayHello();
		SteveJobs.SayHello();
		alert(BillGates.SayHello==SteveJobs.SayHello);
		


		// 函数的共享 //
		function SayHello () {
			alert('hello, i am '+this.name);
		}
		function Person (name) {
			this.name=name;
			this.SayHello=SayHello;
		}

		var BillGates=new Person('Bill gates');
		var SteveJobs=new Person('Steve jobs');

		alert(BillGates.SayHello==SteveJobs.SayHello);



		// 函数的继承关系 //
		function Person (name) {
			this.name=name;
			this.SayHello=function(){
				alert('Hello, i am '+this.name);
			}
		}
		function Employee (name,salary) {
			Person.call(this,name);
			this.salary=salary;
			this.ShowMeTheMoney=function(){
				alert(this.name+' $'+this.salary);
			}
		}
		var BillGates=new Person('Bill gates');
		var SteveJobs=new Employee('Steve jobs',1243);

		BillGates.SayHello();
		SteveJobs.SayHello();
		SteveJobs.ShowMeTheMoney();

		alert(BillGates.constructor==Person);
		alert(SteveJobs.constructor==Employee);

		alert(BillGates.SayHello==SteveJobs.SayHello);

	
		// 创建对象 //
		function myFun(){};
		var anObj1=new myFun();
		var anObj2=new myFun;

		function myFunc(){alert(2);};
		var anObj={};
		myFunc.call(anObj);

		// 函数的几种调用方法 //
		function WhoAmI () {
			alert('i am '+this.name+' of '+typeof(this));
		}
		WhoAmI();

		var BillGates={name:'bill gates'};
		BillGates.WhoAmIs=WhoAmI;
		BillGates.WhoAmIs();

		var SteveJobs={name:'Steve Jobs'};
		SteveJobs.WhoAmI=WhoAmI;
		SteveJobs.WhoAmI();

		WhoAmI.call(BillGates);
		WhoAmI.call(SteveJobs);

		BillGates.WhoAmIs.call(SteveJobs);
		SteveJobs.WhoAmI.call(BillGates);

		WhoAmI.WhoAmI=WhoAmI;
		WhoAmI.name='who am i';
		WhoAmI.WhoAmI();

		({name:'nobody',WhoAmI:WhoAmI}).WhoAmI();


		// 函数对象可以通过下标访问属性和方法 //
		//var anObject={};
		var anObject=function(){};

		anObject.aProperty='Property of object';
		anObject.aMethod=function(){
			alert('object\'s Method is calling')
		};

		alert(anObject['aProperty']);
		anObject['aMethod']();

		for(var s in anObject)
		{
			alert(s+' is a '+typeof(anObject[s]));
		}


		
		// 函数也是对象,具有属性 //
		function Sing()
		{
			alert(Sing.author+': '+Sing.poem);

			alert(Sing.arguments[0]);
		}
		Sing.author='李白';
		Sing.poem='床前明月光,疑是地上霜';
		Sing();

		Sing.author='杜甫';
		Sing.poem='女儿琵琶怨,已唱三千年';
		Sing();


		// caller 属性 //
		function WhoCallMe()
		{
			alert(WhoCallMe.toString());
			alert('my caller is:'+WhoCallMe.caller);
		}
		function CallerA () 
		{
			WhoCallMe();
		}
		function CallerB()
		{
			WhoCallMe();
		}
		alert(WhoCallMe.caller);
		WhoCallMe();
		CallerA();
		CallerB();


		// var 变量 //
		var yourname='王菲';
		myname='cc';
		alert(myname+' and '+yourname);

		ChangeNames();

		function ChangeNames () {
			alert('your old name is:'+ yourname);
			alert('my old name is:'+myname);
			var yourname='your newname';
			myname='my newname';
			alert(myname+ ' and '+yourname);
		}

		alert(myname+ ' and '+yourname);


		// 函数 //
		function myfunc()
		{
			alert("hello");

			//alert(myfunc.caller)
			alert(typeof(myfunc));
		}
		myfunc();

		var myfunc=function() 
		{
			alert("var myfunc")
		}
		myfunc();


		// 数据类型 //
		function datatype()
		{
			//alert("123"==123);//true
			//alert("123"===123);//false
			alert(null!==undefined);
		}
	*/
	</script>
</head>
<body>
	<input type="button" name="btn" value="数据类型" onclick="datatype()" />
	<input type="button" name="btn" value="函数" onclick="myfunc()" />
</body>